■ PCのキーボードスイッチを読み込んで液晶に表示する
![]()
<PS2概要>
(1) 全般
パソコンのキーボードの信号はPS2と呼ばれるシリアルインターフェースで通信がおこなわれています。IBMがつくった
2線式クロック同期方式双方向半二重シリアル通信で通信速度は9600bpsです。マウスにも使われています。キー
ボードの各キーにはアスキーコードとはことなるスキャンコードと呼ばれるコードがわりあてられています。パソコンの
場合キーボードが押されると以下のように信号がPCのアプリケーションソフトへと送られていきます。
@ キーボードが押される
Aキーボードマイコン(intel 8051等)がダイナミックスキャンにより押されたキーを特定する
Bキーボードマイコンはスキャンコードを生成して同期クロック(CLK)と共にデータ(DATA)をPS2コネクタに
出力する。
・クロックはDATAを送る時だけ発生し、クロックの速度は9600bpsです。
・DATAは1〜4バイトで 1バイト毎に2msec程度の間隔で区切って送られてくる
・DATAに出力される信号はスキャンコード以外にACKやキーボードのIDなどもある。
C信号がキーボードケーブル経由で伝送される。
Dパソコン側ではキーボードコントローラ(intel 8042等)がPS2シリアル信号をスキャンコードに変換する
EさらにこのスキャンコードをBIOSがASCIIコードに変換する
FBIOS→OS→アプリケーションソフトとASCIIコードが伝送される
【PS2インターフェースに関する技術情報】
★OADGテクニカル・リファレンス
★ Sazanami Online PS/2 インターフェイスの研究
(2) コネクタ & ハードウェア
・ コネクタはミニDINと呼ばれるコネクタが使われています。
・ PC側のコネクタ(メス)のピンアサイン(ピン配列)を以下に示します。2番、6番はNCで4番が電源、3番が
グランド、1番、5番が信号ラインとなっています。
ピン配列
1 … DATA
2 … NC
3 … GND
4 … +5V
5 … CLK
6 … NC
・ 1番DATA信号と5番CLK信号のインターフェースはKeyBoard側、PC側共に電気回路的には全く同じで4.7KΩ
プルアップによるNPNトランジスタオープンコレクタ回路になっています。入力と出力は別ポートの構成となって
います。 したがって PC側の所要ポート数は 合計4ポートとなります。 (下図 左 参照)
実際に製作したものは、少ないポート数でPS2インターフェースを実現する観点からPICの流れ出し電流許容値
が25mAと大きいことを利用して信号ラインに直列にR=150Ωの抵抗を挿入することとしました。(下図 右参照)
★ KeyBoard側のトランジスタがON(ON電圧=0.4V)、PIC側のポートが出力モード”High”の場合を実測
するとPIC側のポートの電圧は3.6Vでした。したがって、この時のPICの出力電流は
I=(3.6V-0.4V)/150Ω = 21.3mA ( < 25mA → OK )
また、PICの入力レベル”High”はTTLレベルの2.0V以上とと規定されています。この面からもチェック
してみますと
3.6V > 2.0V ( → OK )
となります。
★ 一方、KeyBoard側のトランジスタがOFFで PIC側が”Low”の場合のKeyBoard側の出力電圧を実測して
みると めのこ計算値 0.54V (=150Ω/(150Ω+4.7KΩ)×(5V - 0.4V) + 0.4V)より小さな0.4Vで
した。 KeyBoard側のLowレベルのスレッシュホールドレベルはTTLレベルかCMOSレベルかわかりま
せんが
0.4V < 0.8V (TTLレベルの場合 → OK )
0.4V < 1.5V (CMOSレベル場合 at Vcc=+5V → OK )
と問題ないことがわかります。

(3) パルス信号
(3−1) 全般
・ 信号はKeyBoard側からPC側、PC側からKeyBoard側の両方ともKeyBoard側のCLKからのクロックに同期して
信号の授受がおこなわれます。クロックは9600bps→9.6KHz duty=50%で、信号授受をおこなう時だけ出力
されます。
・ 1〜4バイトのデータ(可変長バイト)がやりとりされます。 複数のバイトデータが送られる時は1バイトづつ
2msec程度の間隔をおいておくられます。1バイトのデータは下図のようにスタートビット、8ビットのデータ、
パリティビット、ストップビットから構成されています。パリティは奇数パリティです。
データはLSBから すなわちbit0、bit1、…bit7と送りだされます。 KeyBoard側よりPIC側へ信号が送られ
る場合は CLKのパルスが立ち下がりとなった時にDATA信号は出力されているのでこのタイミングで
割込みによってDATAを読み込みます。また PIC側よりKeyBoard側へ信号を送る時はCLKのパルスが
立ち下がったことを検出した時は、1μsec以内にDATA信号をDATAラインに出力する。
下図はKeyBoard側よりPIC側へ 11111010(2進表示:プログラム上の表記は0b11111010
16進表示で
表記すれば 0xfa)と云うデータを送った場合の例を示しています。

(3−2) スキャンコード
キーボードの各キーにはアスキーコードとは異なるスキャンコードと呼ばれるコードが割り当てられています。
キーボードを押した時(Make)と離した時(Brake)のそれぞれの瞬間にスキャンコードが送信されます。Brakeの
スキャンコードはF0の後にMakeのスキャンコードが追加されたものです。 キーによってはMakeのスキャンコードが
2バイトのものもあります。 したがってこの場合のBrakeのスキャンコードは、3バイトのデータが2msec間隔で
つづけて送られてきます。 (日本語109キーボードのスキャンコード表 参照)
<試作品仕様>
・ キーボードを押して離すと液晶(16文字:英数字&記号 × 2段)に押したキーボードの文字と送られてきた
スキャンコードが16進表示で1バイトづつあとから送られてきた順番に表示されること
★上段 (左隅から) …… 最後に押したキーボードの文字 M[0]L[0] M[1]L[1] M[2]L[2] M[3]L[3]
★下段 (左隅から) …… M[4]L[4] M[5]L[5] M[6]L[6]
M[7]L[7] M[8]L[8]
(注) M[i]L[i] ( i = 0〜8) : 最後から i番前に送られてきた1バイトデータを16進表示したもの
L[i]が下位4ビット、M[i]が上位4ビットをあらわす。
(例) キーボードを”y” ”b ” と 押した後 ”k” を押して指を離すと液晶には以下のように表示される
k 42 f0 42 32
f0 32 35 f0 35
・ シフトキーを押しながらキーボードを押すとシフト文字(アルファベットの大文字など)が表示されること
・ Caps Lock ができること。尚、この時キーボードのLEDが点灯すること
<試作品外観>
下記の写真には上記回路図にはない、また本テーマと関係のない部品が多々写っています。

<回路図>
PIC18F452をつかった場合の回路図を以下に示します。(→回路図ののPDFファイル)

| 以下のプログラム例の中にある液晶表示器制御ライブラリ 1llcd_lib.cは 後閑哲也さんが設計されたものです。 |
<プログラム例>
//--------------------------------------
//--------------------------------------
// 構成
// KeyBoard → PIC18F452 → 16文字キャラクタ液晶
// ★ shift capsLock 対応
// PICからキーボードへの送信
// @ CLK線を60μsec以上インアクティブ(L)にする
// A 次にDATA線も60μsec程度インアクティブ(L)にします
// B DATA線、CLK線をア60μsec程度クティブ(H)にする
// C スタートビットをDATA線に出力し DATA線にキーボードがクロックを出力するのを待つ
// D CLK線にクロックの立下りを検出したらDATA線にデータを出力する
// E ビット8には奇数パリティを計算して設定する
#include "18f452.h"
#use delay(clock=40000000)
#FUSES EC,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#use RS232(BAUD=9600,XMIT=PIN_C6,RCV=PIN_C7) // TX=RC6,RX=RC7
#byte INTCON3=0xFF1 //アドレス0xFF1の変数をINTCON3と命名
#byte TRISB=0xF93
#define Transmit 1
#define Receive 0
//////// Port define and link LCD library
#define mode 0
// No1 液晶
#define input_x input_D
#define output_x output_D
#define set_tris_x set_tris_D
#define rs PIN_D2 //chip select
#define stb PIN_D0 //strobe
#include <1lcd_lib.c>
#include "ScanTable1.h"
unsigned long int BitReceiveData = 0,BitSendData = 0;
int BitReceiveCount = 0,ix,TRMode = Receive,BitSendCount =0;
char ScanData[100],AsciiData[100];
short int Flag,Shift = 0,Caps = 0,CapsNow = 0,CapsTrigger =0,LockTrigger = 0;
unsigned long int temp;
void Lcd() //液晶表示
{
lcd_cmd(0x01); // 全消去
printf(lcd_data,"%c %x %x %x %x",
AsciiData[ix-1],ScanData[ix-1],ScanData[ix-2],ScanData[ix-3],ScanData[ix-4]); // 他なら 文字表示
lcd_cmd(0xC0);//2行目の先頭へ
printf(lcd_data," %x %x %x %x %x",
ScanData[ix-5],ScanData[ix-6],ScanData[ix-7],ScanData[ix-8],ScanData[ix-9]);
}
unsigned long int Parityx(unsigned long int Datax) // パリティ計算
{
unsigned long int i = 0,Parity = 0;
for(i = 0; i < 8; i ++ )
{
if(bit_test(Datax,i) == 1)Parity = Parity + 1;
}
if((Parity % 2) == 1) Parity = 0;
else Parity = 1;
return Parity;
}
void BitSendDataSet() //奇数パリティデータのセット 及び 送信データのセット
{
unsigned long int Parity;
Parity = Parityx(BitSendData);
if(Parity == 1)bit_set(BitSendData,8);
else bit_clear(BitSendData,8);
BitSendData =BitSendData << 1;
}
void TransmitModeSet(){ //キーボード側に送信したい旨連絡する
set_tris_b(0x00); //B0(DATA線)、 B1(CLK線)をともに出力ポートに設定
output_low(PIN_B1); // CLK線→L
output_high(PIN_B0);
delay_us(60);
output_low(PIN_B0); // DATA線→L
delay_us(60); //60μsecごとにキーボードはラインをチェックするので15msec待つ
//キーボードi8042はホストがデータを送信しようとしていることを認識したはず
set_tris_b(0b00000010); //B0(DATA線)を出力ポートに B1(CLK線)を入力ポートに設定
//キーボードからrのクロックに同期してB0からの出力の準備をおこなう
output_low(PIN_B0); // DATA線→L
TRMode = Transmit;
}
void Transmitx() //送信関数
{
output_bit(PIN_B0,(bit_test(BitSendData,0)));
BitSendData = BitSendData >> 1;
BitSendCount++;
if(BitSendCount >= 12){
TRMode = Receive; //
BitSendCount = 0;
}
}
void Receivex(){ //受信関数
temp = (unsigned long int) input(PIN_B0); // Clock H --> L
if((Flag == 0) && (temp == 0))Flag = 1;
if(Flag == 1)
{
BitReceiveData = (BitReceiveData >> 1) ;//このビットシフト回数は9回である。10回ではない
temp = (temp << 10);
BitReceiveData = BitReceiveData + temp ;
BitReceiveCount++;
if(BitReceiveCount >= 10)
{
BitReceiveData = BitReceiveData >> 2; // 下2桁の無効データを削除
ScanData[ix] = (byte)(BitReceiveData & 0xFF);
//-------------------シフトキーがおされているかどうかの判別
if( (ScanData[ix] == 0x12)||(ScanData[ix] == 0x59))Shift = 1;// シフトキーMake操作の場合
if( ((ScanData[ix] == 0x12)||(ScanData[ix] == 0x59))
&& (ScanData[ix-1] == 0xF0))Shift = 0;// シフトキーBreak操作の場合
//-----Capsロック判別
//-------Caps Lock キーが押されているかどうかの判別
if(ScanData[ix] == 0x58)
{
CapsNow = 1;
}
if( (ScanData[ix] == 0x58) && (ScanData[ix-1] == 0xF0))// CapsLock : Brake
{
CapsNow = 0;
}
if( ( (ScanData[ix] == 0x58) &&
!((ScanData[ix-1] == 0xf0) || (ScanData[ix-1] == 0x58) ) ) ||
((ScanData[ix] == 0x58) && (ScanData[ix-1] == 0x58) && (ScanData[ix-2] == 0xf0)) )
{
CapsTrigger = 1;
}
else CapsTrigger = 0;
//---------------Caps Lock 状態かどうかの判別
if( (CapsTrigger == 1) && (Shift == 1))
{
LockTrigger = 1;
}
else LockTrigger = 0;
AsciiData[ix] = ScanToAscii(ScanData[ix],(Shift | Caps));
// L R Shift or Caps
if((ScanData[ix] == 0x12) || (ScanData[ix] == 0x59) || (ScanData[ix] == 0x58))
{
AsciiData[ix] = AsciiData[ix -2];
}
if( (ScanData[ix] <= 0x80) )
{
lcd_cmd(0x01); // 全消去
printf(lcd_data,"%c %x %x %x %x",
AsciiData[ix],ScanData[ix],ScanData[ix-1],ScanData[ix-2],ScanData[ix-3]); // 他なら 文字表示
lcd_cmd(0xC0);//2行目の先頭へ
printf(lcd_data," %x %x %x %x %x",
ScanData[ix-4],ScanData[ix-5],ScanData[ix-6],ScanData[ix-7],ScanData[ix-8]);
}
ix++; if(ix >=100)ix =0;
BitReceiveCount = 0;
BitReceiveData = 0x0000;
Flag = 0;
}
}
}
#INT_EXT1 //B1:Clk
void KeyBoardClk()
{
switch(TRMode){
case Receive:// スタンバイ状態 キーボードからの信号待ち
Receivex();
break;
case Transmit:// キーボードへの送信モード
Transmitx();
break;
default: break;
}
}
void CapsLockLed() //CapsLockLedのON/OFF制御
{
if(LockTrigger == 1)
{
disable_interrupts(INT_EXT1);
disable_interrupts(GLOBAL);
BitSendData = 0xFFED;
BitSendDataSet();
TransmitModeSet();
enable_interrupts(INT_EXT1); // Set up EXT1
enable_interrupts(GLOBAL);
do
{
}while(ScanData[ix-1] != 0xfa);
ScanData[ix-1] = 0xf8;
disable_interrupts(INT_EXT1);
disable_interrupts(GLOBAL);
if(Caps == 0)
{
BitSendData = 0xFF04; //CapsLockLED ON
Caps = 1; //
}
else
{
BitSendData = 0xFF00; //CapsLockLED OFF
Caps = 0;
}
BitSendDataSet();
TransmitModeSet();
enable_interrupts(INT_EXT1); // Set up EXT1
enable_interrupts(GLOBAL);
do
{
}while(ScanData[ix-1] != 0xfa);
if(ScanData[ix-2] == 0xf8)ScanData[ix-2] = 0xfa;
LockTrigger = 0;
}
}
void InitialCheck() //電源投入時のPICとキーボード間の送受信
{
//------- リセット命令 FF
BitSendData = 0xFFFF; //キーボードリセット命令
BitSendDataSet(); //パリティ計算を行い送信データをセットする
TransmitModeSet(); //キーボード側に送信したい旨連絡し 送信モードでINT_EXT1にクロックがくるのを待つ
enable_interrupts(INT_EXT1); // INT_EXT1が外部割込みを検出できるように割込みを許可する
enable_interrupts(GLOBAL);
do{ //最初にAck(0xFA : コマンドに対する正しく受け取られた応答)がキーボードからかえってくる
}while(ScanData[ix-1] != 0xAA);//その後BAT(0xAA:Basic Assurance Test)が正しく終了したがキーボードからかえってくる
disable_interrupts(INT_EXT1);
disable_interrupts(GLOBAL);
BitSendData = 0xFFF2; //識別情報(キーボードorマウス? どのようなキーボードか?) を要求
BitSendDataSet();//パリティ計算を行い送信データをセットする
TransmitModeSet();//キーボード側に送信したい旨連絡し 送信モードでINT_EXT1にクロックがくるのを待つ
enable_interrupts(INT_EXT1); // INT_EXT1が外部割込みを検出できるように割込みを許可する
enable_interrupts(GLOBAL);
do{ //最初にAck(0xFA : コマンドに対する正しく受け取られた応答)がキーボードからかえってくる
}while(ScanData[ix-1] != 0x83);//日本語キーボードの場合0xAB,0x83がかえってくる
disable_interrupts(INT_EXT1);
disable_interrupts(GLOBAL);
BitSendData = 0xFFED; //キーボードのLED点灯、消灯要求
BitSendDataSet();
TransmitModeSet();
enable_interrupts(INT_EXT1); // Set up EXT1
enable_interrupts(GLOBAL);
do{
}while(ScanData[ix-1] != 0xfa);
ScanData[ix-1] = 0xf8;
disable_interrupts(INT_EXT1);
disable_interrupts(GLOBAL);
BitSendData = 0xFF00;
BitSendDataSet();
TransmitModeSet();
enable_interrupts(INT_EXT1);
enable_interrupts(GLOBAL);
do{
}while(ScanData[ix-1] != 0xfa);
if(ScanData[ix-2] == 0xf8)ScanData[ix-2] = 0xfa;
Lcd(); //液晶表示
}
main(){
TRISB = 0xFF;//B port all input mode
INTCON3 = 0b01000000;// 割込みレベル : 高位 (bit7)(bit6)(bit5)(bit4)(bit3)(bit2)(bit1)(bit0)
// = (X2割込レベル)(X1割込レベル)(意味無)(X2割込許可)(X1割込許可)(意味無)(X2割込フラグ)(X1割込フラグ)
ext_int_edge( 1, H_TO_L); // PIN_B1 からの外部割込み
lcd_init();
lcd_cmd(0b00001100); // カーソル:OFF ブリンク:OFF
lcd_clear();
printf(lcd_data,"start!!");
delay_ms(1000); // KeyBoard POR timeは MAX500msec
InitialCheck(); //電源投入時のPICとキーボード間の送受信
while(1)
{
CapsLockLed(); //CapsLockLedのON/OFF制御
}
return 0;
}
//-------------------------------------------------------------------------------------------------
//*******************************************
//インクルードファイル ScanTable1.h
//*******************************************
char ShiftAscii(char ScanData)
{
char temp;
switch(ScanData)
{
case 0x16: temp = '!'; break;
case 0x1E: temp = '"'; break;
case 0x26: temp = '#'; break;
case 0x25: temp = '$'; break;
case 0x2E: temp = '%'; break;
case 0x36: temp = '&'; break;
case 0x3D: temp = 0x27; break;
case 0x3E: temp = '('; break;
case 0x46: temp = ')'; break;
case 0x45: temp = 0x7E; break;
case 0x1C: temp = 'A'; break;
case 0x32: temp = 'B'; break;
case 0x21: temp = 'C'; break;
case 0x23: temp = 'D'; break;
case 0x24: temp = 'E'; break;
case 0x2B: temp = 'F'; break;
case 0x34: temp = 'G'; break;
case 0x33: temp = 'H'; break;
case 0x43: temp = 'I'; break;
case 0x3B: temp = 'J'; break;
case 0x42: temp = 'K'; break;
case 0x4B: temp = 'L'; break;
case 0x3A: temp = 'M'; break;
case 0x31: temp = 'N'; break;
case 0x44: temp = 'O'; break;
case 0x4D: temp = 'P'; break;
case 0x15: temp = 'Q'; break;
case 0x2D: temp = 'R'; break;
case 0x1B: temp = 'S'; break;
case 0x2C: temp = 'T'; break;
case 0x3C: temp = 'U'; break;
case 0x2A: temp = 'V'; break;
case 0x1D: temp = 'W'; break;
case 0x22: temp = 'X'; break;
case 0x35: temp = 'Y'; break;
case 0x1A: temp = 'Z'; break;
case 0x4E: temp = '='; break;
case 0x55: temp = '~'; break;
case 0x6A: temp = '|'; break;
case 0x54: temp = '`'; break;
case 0x5B: temp = '{'; break;
case 0x4C: temp = '+'; break;
case 0x52: temp = ':'; break;
case 0x5D: temp = '}'; break;
case 0x41: temp = '<'; break;
case 0x49: temp = '>'; break;
case 0x4A: temp = '?'; break;
case 0x51: temp = '_'; break;
case 0x29: temp = ' '; break;
case 0x71: temp = '.'; break;
case 0x7B: temp = '-'; break;
case 0x79: temp = '+'; break;
default: temp = ScanData; break;
}
return temp;
}
char NoShiftAscii(char ScanData)
{
char temp;
switch(ScanData)
{
case 0x16: temp = '1'; break;
case 0x1E: temp = '2'; break;
case 0x26: temp = '3'; break;
case 0x25: temp = '4'; break;
case 0x2E: temp = '5'; break;
case 0x36: temp = '6'; break;
case 0x3D: temp = '7'; break;
case 0x3E: temp = '8'; break;
case 0x46: temp = '9'; break;
case 0x45: temp = '0'; break;
case 0x1C: temp = 'a'; break;
case 0x32: temp = 'b'; break;
case 0x21: temp = 'c'; break;
case 0x23: temp = 'd'; break;
case 0x24: temp = 'e'; break;
case 0x2B: temp = 'f'; break;
case 0x34: temp = 'g'; break;
case 0x33: temp = 'h'; break;
case 0x43: temp = 'i'; break;
case 0x3B: temp = 'j'; break;
case 0x42: temp = 'k'; break;
case 0x4B: temp = 'l'; break;
case 0x3A: temp = 'm'; break;
case 0x31: temp = 'n'; break;
case 0x44: temp = 'o'; break;
case 0x4D: temp = 'p'; break;
case 0x15: temp = 'q'; break;
case 0x2D: temp = 'r'; break;
case 0x1B: temp = 's'; break;
case 0x2C: temp = 't'; break;
case 0x3C: temp = 'u'; break;
case 0x2A: temp = 'v'; break;
case 0x1D: temp = 'w'; break;
case 0x22: temp = 'x'; break;
case 0x35: temp = 'y'; break;
case 0x1A: temp = 'z'; break;
case 0x4E: temp = '-'; break;
case 0x55: temp = '^'; break;
case 0x6A: temp = 0x5C; break;// ¥
case 0x54: temp = '@'; break;
case 0x5B: temp = '['; break;
case 0x4C: temp = ';'; break;
case 0x52: temp = ':'; break;
case 0x5D: temp = ']'; break;
case 0x41: temp = ','; break;
case 0x49: temp = '.'; break;
case 0x4A: temp = '/'; break;
case 0x51: temp = 0x5C; break;//¥
case 0x29: temp = ' '; break;
case 0x71: temp = '.'; break;
case 0x7B: temp = '-'; break;
case 0x79: temp = '+'; break;
default: temp = ScanData; break;
}
return temp;
}
char ScanToAscii( char ScanData ,int Shift )
{
char AsciiTemp;
if(Shift == 1)
{
AsciiTemp = ShiftAscii(ScanData);
}
else AsciiTemp = NoShiftAscii(ScanData);
return AsciiTemp ;
}
//---------------------------------------------------------------------------------------------
//**************************************
//インクルードファイル 1lcd_lib.c
//このファイルは後閑哲也さんが設計されたものです
//**************************************
///////////////////////////////////////////////
// 液晶表示器制御ライブラリ
// 内蔵関数は以下
// lcd_init() ----- 初期化
// lcd_cmd(cmd) ----- コマンド出力
// lcd_data(chr) ----- 1文字表示出力
// lcd_clear() ----- 全消去
//////// データ出力サブ関数
void lcd_out(int code, int flag)
{
output_x((code & 0xF0) | (input_x() & 0x0F));
if (flag == 0)
output_high(rs); //表示データの場合
else
output_low(rs); //コマンドデータの場合
delay_cycles(4); //NOP 1
output_high(stb); //strobe out
delay_cycles(8); //NOP 2
output_low(stb); //reset strobe
}
//////// 1文字表示関数
void lcd_data(int asci)
{
lcd_out(asci, 0); //上位4ビット出力
lcd_out(asci<<4, 0); //下位4ビット出力
delay_us(50); //50μsec待ち
}
/////// コマンド出力関数
void lcd_cmd(int cmd)
{
lcd_out(cmd, 1); //上位4ビット出力
lcd_out(cmd<<4, 1); //下位4ビット出力
delay_ms(2); //2msec待ち
}
/////// 全消去関数
void lcd_clear()
{
lcd_cmd(0x01); //初期化コマンド出力
delay_ms(15); //15msec待ち
}
/////// 初期化関数
void lcd_init()
{
set_tris_x(mode); //モードセット
delay_ms(15);
lcd_out(0x30, 1); //8bit mode set
delay_ms(5);
lcd_out(0x30, 1); //8bit mode set
delay_ms(1);
lcd_out(0x30, 1); //8bit mode set
delay_ms(1);
lcd_out(0x20, 1); //4bit mode set
delay_ms(1);
lcd_cmd(0x2E); //DL=0 4bit mode
lcd_cmd(0x08); //display off C=D=B=0
lcd_cmd(0x0D); //display on C=D=1 B=0
lcd_cmd(0x06); //entry I/D=1 S=0
lcd_cmd(0x02); //cursor home
}
//-----------------------------------------------------------------------------------------------
<動作結果>
・以下に キーボードから”y”、”b ” と キーインして ”k” を押して指を離した場合の液晶表示を
示します。
